package com.hsx.dao;

import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class BaseDao {
    private static String driver;
    private static String url;
    private static String user;
    private static String password;

    static {
        Properties properties = new Properties();
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver = properties.getProperty("driver");
        url = properties.getProperty("url");
        user=properties.getProperty("user");
        password=properties.getProperty("password");
    }
//    获取数据库连接
    public static Connection getConnection(){
        Connection connection=null;
        try {
            Class.forName(driver);
            connection=DriverManager.getConnection(url,user,password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

//    查询公共类(5个参数）
    public static ResultSet execute(Connection connection,String sql,Object[] params,ResultSet resultSet,PreparedStatement pstm) throws SQLException {
//        {    params是一个计算机函数，表示函数的参数是可变个数的，即可变的方法参数，
//        就像DELPHI 里 WRITELN 函数一样，用于表示类型相同，但参数数量不确定。
//        例如，params(int a)     }
//        这里得params数组类型不确定，所以用Object
        pstm = connection.prepareStatement(sql);
//        如果i比该params长度小，那么就不断自增
        for (int i = 0; i < params.length; i++) {
//            占位符从1开始，但是我们数组从0开始
//            让比如第1(i+1)个数等于数组里的第0(i)个
            pstm.setObject(i+1,params[i]);
        }
//        resultSet为执行sql得返回值
        resultSet=pstm.executeQuery();
        return resultSet;
    }
//    增删改公共类（3个参数）
    public static int execute(Connection connection,String sql,Object[] params) throws SQLException {

        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            preparedStatement.setObject(i+1,params[i]);
        }
//        resultSet为执行sql得返回值
        int updateRows=preparedStatement.executeUpdate();
        return updateRows;
    }

    //关闭资源
    public static boolean closeResource(Connection connection,ResultSet resultSet,PreparedStatement preparedStatement){
        boolean flag=true;
        if (resultSet!=null){
            try {
                resultSet.close();
                resultSet=null;
            } catch (SQLException e) {
                e.printStackTrace();
            }flag=false;
        }
        if (connection!=null){
            try {
                connection.close();
                connection=null;
            } catch (SQLException e) {
                e.printStackTrace();
            }flag=false;
        }
        if (preparedStatement!=null){
            try {
                preparedStatement.close();
                preparedStatement=null;
            } catch (SQLException e) {
                e.printStackTrace();
            }flag=false;
        }
        return flag;
    }



}
//preparedStatement和Statement得区别
//        而前者是普通的Statement对象。PreparedStatement对象不仅包含了SQL语句，
//        而且大多数情况下这个语句已经被预编译过，因而当其执行时，只需DBMS运行SQL语句，
//        而不必先编译。当你需要执行Statement对象多次的时候，PreparedStatement对象将会大大降低运行时间，
//        当然也加快了访问数据库的速度。这种转换也给你带来很大的便利，不必重复SQL语句的句法，
//        而只需更改其中变量的值，便可重新执行SQL语句。选择PreparedStatement对象与否，
//        在于相同句法的SQL语句是否执行了多次，而且两次之间的差别仅仅是变量的不同。
//        如果仅仅执行了一次的话，它应该和普通的对象毫无差异，体现不出它预编译的优越性。
